﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tycho.Runtime;
using System.Windows;
using Tycho.Transactions;
using Tycho.Language;

namespace Tycho.Peyote {
    public class Environment {
        public static Namespace PeyoteNamespace = Namespaces.Tycho.GetNamespace("peyote");
        public Namespace DefaultNamespace { get; private set; }
        public ResourceDictionary Resources { get; private set; }
        public TransactionalTopLevel TopLevel { get; private set; }
        public GlyphPresenterRegistry Presenter { get; private set; }
        public IGlyphLayout Layout { get; private set; }
        public EvaluationDependencyEngine EvaluationDependencyEngine { get; private set; }
        private Window MainWindow;

        public Environment (Window mainWindow, IGlyphLayout layout) {
            DefaultNamespace = PeyoteNamespace;
            TopLevel = new TransactionalTopLevel (DefaultNamespace);
            TopLevel.AddModule(AssemblyModuleLoader.LoadAssembly(PeyoteNamespace, typeof (Environment).Assembly));
            MainWindow = mainWindow;
            Presenter = new GlyphPresenterRegistry (this);
            ConfigurePresenters ();
            Layout = layout;
            EvaluationDependencyEngine = new EvaluationDependencyEngine ();
        }

        private void ConfigurePresenters () {
            Presenter.Presenters.Add (new IntegerPresenter ());
            Presenter.Presenters.Add (new SymbolPresenter ());
            Presenter.Presenters.Add (new StructurePresenter ());
            Presenter.Presenters.Add (new SetPresenter ());
            Presenter.Presenters.Add (new ListPresenter ());
        }

        public void Exit () {
            MainWindow.Close ();
        }

        public TransactionalObjectManager Transaction (TransactionalObjectManager.TransactionDelegate transactionWork) {
            return Transaction (transactionWork, null);
        }

        public TransactionalObjectManager Transaction (TransactionalObjectManager.TransactionDelegate transactionWork, TransactionalObjectManager.TransactionDelegate ifTransactionFails) {
            return TransactionalObjectManager.RunTransaction (transactionWork, ifTransactionFails);
        }
    }
}
